<!DOCTYPE html>
<html lang="en" style="">
<head>
	<title>09-Logger | PhalApi - A light-weight PHP framework for API</title>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<link rel="icon" href="http://webtools.qiniudn.com/dog_catch.png" type="image/x-icon" />
	<meta name="description" content="PhalApiis A light-weight PHP framework for API!">
	<meta name="keywords" content="PhalApi,phalapi,phalapi API develop,backend framework,restful,web services,saas,microservice,API framework,open API framework,PHP API framework,php web framework">
	<meta name="author" content="dogstar">

	<link rel="stylesheet" type="text/css" href="./../..//css/screen.css?20150211" />
</head>

<body>
<a href="https://github.com/phalapi/phalapi">
	<img alt="Fork me on GitHub" data-canonical-src="http://7xslqv.com1.z0.glb.clouddn.com/images/2/2d/9e69c0ebaff22a24e241a0244532e.png" src="http://7xslqv.com1.z0.glb.clouddn.com/images/2/2d/9e69c0ebaff22a24e241a0244532e.png" style="position: absolute; top: 0; right: 0; border: 0;">
</a>

<!-- 最顶部的语言(S) -->
<div class="grid-wrapper navbar desktop-only">
	<div class="grid">
		<div class="grid__cell">
			<ul id="language-switchers" class="navbar__links navbar--left">
                <li class="menu-item"><a title="PhalApi官方网站中文版" href="/" class="menu-item__link">Chinese</a></li>
				<li class="menu-item"><a title="English version of PhalApi website" href="/wikis/en/" class="menu-item__link">English</a></li>
			</ul>
			<ul id="util-menu" class="navbar__links navbar--right navbar--vertical-separator">
				<li class="menu-item"><a href="#" class="menu-item__link contact-us-spec">Welcome Here!</a></li>
			</ul>
		</div>
	</div>
</div>
<!-- 最顶部的语言(E) -->

<!-- 顶部导航菜单(S) -->
<div class="grid-wrapper desktop-only">
	<div class="grid">
		<div class="grid__cell">
			<div class="header__header-wrapper">
				<a title="PhalApi" href="http://www.phalapi.net" class="header__logo"><img src="http://webtools.qiniudn.com/master-LOGO-20150410_33.jpg" id="tw-logo" alt="PhalApi"></a>
				<ul id="main-menu" class="header__menu">
					<li class="menu-item"><a href="http://qa.phalapi.net/" class="menu-item__link insights-spec" target="_blank">Community</a></li>
					<li class="menu-item"><a href="https://github.com/phalapi/phalapi" class="menu-item__link insights-spec" target="_blank">Download</a></li>
					<li class="menu-item"><a href="/wikis/en/" class="menu-item__link events-spec" target="_blank">Wikis</a></li>
    				<li class="menu-item"><a href="/docs_en/" class="menu-item__link events-spec" target="_blank">Classes docs</a></li>
					<li class="menu-item"><a href="http://demo.phalapi.net/" class="menu-item__link products-spec" target="_blank">Demo</a></li>
					<li class="menu-item"><a href="/about.html" class="menu-item__link about-us-spec" target="_blank">About us</a></li>
				</ul>
			</div>
		</div>
	</div>
</div>
<!-- 顶部导航菜单(E) -->


    <div class="grid-wrapper">
        <div class="grid">
            <div class="grid__cell">
                <h2>9.1 PHP Uniform Logger Interface</h2>
<p>A great logger interface has been describeted at <a href="http://www.php-fig.org/psr/psr-3/">Logger Interface</a>.<br />
<img src="http://webtools.qiniudn.com/20150411005257_2caf170c179348eca546ba5332837d09" alt="" />  </p>
<h2>9.2 PhalApi Simpler Logger Interface</h2>
<p>After many project developments in real world, we found that actually in most time we only use some of these interfaces, not all of them. For simplicity, PhalApi only provide three kinds of interfaces in <a href="https://github.com/phalapi/phalapi/blob/release-en/PhalApi/PhalApi/Logger.php">PhalApi_Logger</a>.  </p>
<ul>
<li>ERROR level  </li>
<li>INFO level  </li>
<li>
<p>DEBUG level  </p>
<p>We will explain them in more details.  </p>
</li>
</ul>
<h3>(1) ERROR Level</h3>
<p>When system exception happens, which means something happening unexpectly, we can log the context as ERROR level. For example, user fail to pay or program fail to insert new data into database.  </p>
<p>We can use <code>PhalApi_Logger::error()</code> to log error information as below. It's very simple as you can see. </p>
<pre><code>// only record decription
DI()-&gt;logger-&gt;error('fail to insert DB');

// record decription and more message
DI()-&gt;logger-&gt;error('fail to insert DB', 'try to register user dogstar');

// record decription and context data
$data = array('name' =&gt; 'dogstar', 'password' =&gt; '123456');
DI()-&gt;logger-&gt;error('fail to insert DB', $data);</code></pre>
<p>These loggers will be saved into log files at default.  </p>
<pre><code>$ tailf ./PhalAPi/Runtime/log/201502/20150207.log 
2015-02-07 20:37:55|ERROR|fail to insert DB
2015-02-07 20:37:55|ERROR|fail to insert DB|try to register user dogstar
2015-02-07 20:37:55|ERROR|fail to insert DB|{"name":"dogstar","password":"123456"}</code></pre>
<h3>(2) INFO Level</h3>
<p>It's necessary to record some business opertaions history at key point in project. These INFO loggs can help us to locate and fix bugs in the future. We can also collect, analyze , dig into these loggs, and do some statistics. In summary, they are useful, because they contain important business information from ou clients.  </p>
<p>We can use <code>PhalApi_Logger::info()</code> to log business information as <code>PhalApi_Logger::error()</code> above.  </p>
<pre><code>// record infomation
DI()-&gt;logger-&gt;info('add user exp', array('name' =&gt; 'dogstar', 'before' =&gt; 10, 'addExp' =&gt; 2, 'after' =&gt; 12, 'reason' =&gt; 'help one more phper'));

// log in file
2015-02-07 20:48:51|INFO|add user exp|{"name":"dogstar","before":10,"addExp":2,"after":12,"reason":"help one more phper"}</code></pre>
<h3>(3) DEBUG Level</h3>
<p>ERROR and INFO log are usually used in production environment, while DEBUG log is only used in development environment.  </p>
<p>Here are some examples of <code>PhalApi_Logger::debug()</code>.  </p>
<pre><code>DI()-&gt;logger-&gt;debug('just for test');

DI()-&gt;logger-&gt;debug('just for test', 'some description ...');

DI()-&gt;logger-&gt;debug('just for test', array('name' =&gt; 'dogstar', 'password' =&gt; '******'));</code></pre>
<h2>9.3 More Powfull Log Interface</h2>
<p>Besides ERROR, INFO, and DEBUG level log, we can use <code>PhalApi_Logger::log()</code> to log anything as we want.  </p>
<pre><code>DI()-&gt;logger-&gt;log('demo', 'add user exp', array('name' =&gt; 'dogstar', 'after' =&gt; 12));
DI()-&gt;logger-&gt;log('test', 'add user exp', array('name' =&gt; 'dogstar', 'after' =&gt; 12));

// related logs in file
2015-02-07 21:13:27|DEMO|add user exp|{"name":"dogstar","before":10,"addExp":2,"after":12,"reason":"help one more phper"}
2015-02-07 21:15:39|TEST|add user exp|{"name":"dogstar","after":12}</code></pre>
<p>Please NOTE that, the first parameter passed to the method will be tranfered into upper case, which is represented for the type of log.</p>
<h2>9.4 DON NOT Ferget to Set Log Levels</h2>
<p>As we talk above, there are three kinds of log levels.  </p>
<ul>
<li>ERROR log: <code>PhalApi_Logger::LOG_LEVEL_ERROR</code>  </li>
<li>INFO log: <code>PhalApi_Logger::LOG_LEVEL_INFO</code>  </li>
<li>DEBUG log: <code>PhalApi_Logger::LOG_LEVEL_DEBUG</code>  </li>
</ul>
<p>We can choose to record which kinds of logs by specifying log levels in the entrance file.  </p>
<pre><code>DI()-&gt;logger = new PhalApi_Logger_File(API_ROOT . '/Runtime',
    PhalApi_Logger::LOG_LEVEL_DEBUG | PhalApi_Logger::LOG_LEVEL_INFO | PhalApi_Logger::LOG_LEVEL_ERROR);</code></pre>
<h2>9.5 Extend Your Own Logge</h2>
<p>In order to save logs into other storage medium except file, we can extend our own logger interface.  </p>
<p>Take store loggs into database for example.  </p>
<p>Firstly, implement an new logger.  </p>
<pre><code>//$ vim ./Apps/Common/Logger/DB.php

class Common_Logger_DB extends PhalApi_Logger {

    public function log($type, $msg, $data) {
        //TODO save loggs into database ...
    } </code></pre>
<p>Secondly, register <code>DI()-&gt;logger</code> with <code>Common_Logger_DB</code> above.  </p>
<pre><code>DI()-&gt;logger = new Common_Logger_DB($dbConfig,
    PhalApi_Logger::LOG_LEVEL_DEBUG | PhalApi_Logger::LOG_LEVEL_INFO | PhalApi_Logger::LOG_LEVEL_ERROR);</code></pre>
<p>So it is! Check it out by yourself!</p>
            </div>
        </div>
    </div>
    
 <!-- 广告位 -->
<!--
<div class="grid-wrapper desktop-only">
	<p align="center">
		<a href="http://7qnay5.com1.z0.glb.clouddn.com/走向开源的第一年%20-%20PhalApi%202015年度开源总结%20-%20官方出品%20-%2020151214.pdf" target="blank"><img width="950" height="100" src="http://7qnay5.com1.z0.glb.clouddn.com/PhalApi20151213-2.jpg"></a>
		<a href="http://qa.phalapi.net" target="blank"><img width="950" height="100" src="http://7qnay5.com1.z0.glb.clouddn.com/qa_ad_20150615.jpg"></a>
	</p>
</div>
-->

<!-- footer(S) -->
<div class="grid-wrapper footer">
	<div id="footer" class="grid">	

		<div class="grid__cell unit-1-2--lap">
			<h3><img src="http://webtools.qiniudn.com/master-LOGO-20150410_50.jpg" height="50"></h3>
            <p>
            <font size="3px;">PhalApi is a light-weight PHP framework for API.<br/>
                We try to keep PhalApi as stuip simple as possible!
            </font>
			</p>
			<p align="left">
				<font size="2px">&copy;2015-2016 PhalApi All Rights Reserved. 粤ICP备15028808号</font>
				<script type="text/javascript">var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_1255326144'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "s4.cnzz.com/z_stat.php%3Fid%3D1255326144%26show%3Dpic' type='text/javascript'%3E%3C/script%3E"));</script>
			</p>
		</div>	

		<div class="grid__cell unit-1-2--lap">
			<h3>Thanks!</h3>

			<div class="nav">
				<ul class="footer__nav">
					<li class="menu-item"><a href="http://www.oschina.net/" class="menu-item__link" target="_blank">Open Source China</a></li>
					<li class="menu-item"><a href="http://www.phalconphp.com/en/" class="menu-item__link" target="_blank">Phalcon</a></li>
					<li class="menu-item"><a href="https://phpunit.de/manual/3.7/zh_cn/automating-tests.html" class="menu-item__link" target="_blank">PHPUnit</a></li>
					<li class="menu-item"><a href="http://www.thoughtworks.com/cn/" class="menu-item__link" target="_blank">ThoughtWorks</a></li>
				</ul>
			</div>

            <div id="perspectives">
                <div class="email-signup">
                    <strong><a href="https://auth.alipay.com/login/index.htm" target="_blank">Alipay&nbsp;</a>Donate: </strong>chanzonghuang@gmail.com
                </div>
            </div>

			<p>
				<!-- JiaThis Button BEGIN -->
				<div id="ckepop">
				<span class="jiathis_txt">Share: </span>
				<a class="jiathis_button_tsina">Weibo</a>
				<a href="http://www.jiathis.com/share" class="jiathis jiathis_txt jiathis_separator jtico jtico_jiathis" target="_blank">More</a>
				<a class="jiathis_counter_style"></a>
				</div>
				<script type="text/javascript" src="http://v2.jiathis.com/code/jia.js" charset="utf-8"></script>
				<!-- JiaThis Button END -->
				
			</p>
		</div>
	</div>
</div>
<!-- footer(E) -->

</body>

<script type="text/javascript">var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_1254743218'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "w.cnzz.com/q_stat.php%3Fid%3D1254743218' type='text/javascript'%3E%3C/script%3E"));</script>

</html>
